#include "checkboxdelegate.h"

#include <QCheckBox>
#include <QApplication>
#include <QMouseEvent>
#include <QPainter>
#include <QDebug>

CheckBoxDelegate::CheckBoxDelegate(QObject *parent, int column)
    : QStyledItemDelegate(parent)
    , m_delegateColumn(column)
    , m_checkBox(new QCheckBox)
{
    QString qss = "QCheckBox::indicator:unchecked{ \
                   border: none; background-color: transparent; \
                   image:url(:/image/unchecked.png); \
                   } \
                   QCheckBox::indicator:checked { \
                   border: none; background-color: transparent; \
                   image: url(:/image/checked.png); \
                   } \
                   QCheckBox::indicator:indeterminate { \
                   image: url(:/image/indeterminate.png); \
                   }";
    m_checkBox.data()->setStyleSheet(qss);
}

CheckBoxDelegate::~CheckBoxDelegate()
{

}

// 绘制复选框
void CheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItem viewOption(option);
    initStyleOption(&viewOption, index);
    if (option.state.testFlag(QStyle::State_HasFocus))
        viewOption.state = viewOption.state ^ QStyle::State_HasFocus;

    QStyledItemDelegate::paint(painter, viewOption, index);

    if (index.column() == m_delegateColumn)
    {
        bool data = index.model()->data(index, Qt::UserRole).toBool();

        QStyleOptionButton checkBoxStyle;
        checkBoxStyle.state = data ? QStyle::State_On : QStyle::State_Off;
        checkBoxStyle.state |= QStyle::State_Enabled;
        checkBoxStyle.iconSize = QSize(20, 20);
        checkBoxStyle.rect = option.rect;

        m_checkBox.data()->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &checkBoxStyle, painter, m_checkBox.data());
    }
}

// 响应鼠标事件，更新数据
bool CheckBoxDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    QRect decorationRect = option.rect;

    QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
    if (event->type() == QEvent::MouseButtonRelease && decorationRect.contains(mouseEvent->pos()))
    {
        if (index.column() == m_delegateColumn)
        {
            bool data = model->data(index, Qt::UserRole).toBool();
            model->setData(index, !data, Qt::UserRole);
        }
    }

    return QStyledItemDelegate::editorEvent(event, model, option, index);
}



TableHeaderView::TableHeaderView(Qt::Orientation orientation, QWidget *parent, int column)
    : QHeaderView(orientation, parent),
      m_bPressed(false),
      m_bChecked(false),
      m_bTristate(false),
      m_bNoChange(false),
      m_bMoving(false),
      m_delegateColumn(column),
      m_checkBox(new QCheckBox)
{
    // 响应鼠标
    setSectionsClickable(true);

    QString qss = "QCheckBox::indicator:unchecked{ \
                   border: none; background-color: transparent; \
                   image:url(:/image/unchecked.png); \
                   } \
                   QCheckBox::indicator:checked { \
                   border: none; background-color: transparent; \
                   image: url(:/image/checked.png); \
                   } \
                   QCheckBox::indicator:indeterminate { \
                   image: url(:/image/indeterminate.png); \
                   }";
    m_checkBox.data()->setStyleSheet(qss);
}

TableHeaderView::~TableHeaderView()
{

}

// 槽函数，用于更新复选框状态
void TableHeaderView::onStateChanged(int state)
{
    if (state == Qt::PartiallyChecked) {
        m_bTristate = true;
        m_bNoChange = true;
    } else {
        m_bNoChange = false;
    }

    m_bChecked = (state != Qt::Unchecked);

    ///***调用update() 无法触发paintSection接口重绘，导致复选框状态刷新延迟，因此通过用字体样式改变来触发重绘。
    //update();
    // 保存原字体
    QFont originalFont = this->font();
    // 设置一个临时字体
    QFont tempFont = originalFont;
    tempFont.setPointSize(tempFont.pointSize() + 1);
    setFont(tempFont);
    // 恢复原字体
    setFont(originalFont);
}

// 绘制复选框
void TableHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
{
    qDebug() << "33" << logicalIndex;
    painter->save();
    QHeaderView::paintSection(painter, rect, logicalIndex);
    painter->restore();

    if (logicalIndex == m_delegateColumn)
    {
        QStyleOptionButton checkBoxStyle;
        checkBoxStyle.initFrom(this);
        checkBoxStyle.state |= QStyle::State_Enabled;
        checkBoxStyle.rect = rect;

        if (m_bChecked)
            checkBoxStyle.state |= QStyle::State_Sunken;

        if (m_bTristate && m_bNoChange)
            checkBoxStyle.state |= QStyle::State_NoChange;
        else
            checkBoxStyle.state |= m_bChecked ? QStyle::State_On : QStyle::State_Off;
        if (testAttribute(Qt::WA_Hover) && underMouse()) {
            if (m_bMoving)
                checkBoxStyle.state |= QStyle::State_MouseOver;
            else
                checkBoxStyle.state &= ~QStyle::State_MouseOver;
        }

        m_checkBox.data()->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &checkBoxStyle, painter, m_checkBox.data());
        //style()->drawItemPixmap(painter, rect, Qt::AlignCenter, QPixmap(":/images/checkBoxChecked"));
        //style()->drawControl(QStyle::CE_CheckBox, &checkBoxStyle, painter, this);
    }
}

// 鼠标按下表头
void TableHeaderView::mousePressEvent(QMouseEvent *event)
{
    int nColumn = logicalIndexAt(event->pos());
    if ((event->buttons() & Qt::LeftButton) && (nColumn == m_delegateColumn))
    {
        m_bPressed = true;

    }
    else
    {
        QHeaderView::mousePressEvent(event);
    }
}

// 鼠标从表头释放，发送信号，更新model数据
void TableHeaderView::mouseReleaseEvent(QMouseEvent *event)
{
    if (m_bPressed)
    {
        if (m_bTristate && m_bNoChange)
        {
            m_bChecked = true;
            m_bNoChange = false;
        }
        else
        {
            m_bChecked = !m_bChecked;
        }

        ///***调用update() 无法触发paintSection接口重绘，导致复选框状态刷新延迟，因此通过用字体样式改变来触发重绘。
        //update();
        // 保存原字体
        QFont originalFont = this->font();
        // 设置一个临时字体
        QFont tempFont = originalFont;
        tempFont.setPointSize(tempFont.pointSize() + 1);
        setFont(tempFont);
        // 恢复原字体
        setFont(originalFont);

        Qt::CheckState state = m_bChecked ? Qt::Checked : Qt::Unchecked;
        emit stateChanged(state);
    }
    else
    {
        QHeaderView::mouseReleaseEvent(event);
    }

    m_bPressed = false;
}

// 鼠标滑过、离开，更新复选框状态
bool TableHeaderView::event(QEvent *event)
{
    updateSection(0);
    if (event->type() == QEvent::Enter || event->type() == QEvent::Leave)
    {
        QMouseEvent *pEvent = static_cast<QMouseEvent *>(event);
        int nColumn = logicalIndexAt(pEvent->x());
        if (nColumn == m_delegateColumn)
        {
            m_bMoving = (event->type() == QEvent::Enter);

            update();
            return true;
        }
    }
    return QHeaderView::event(event);
}


